
import 'package:flutter/material.dart';
import 'package:xsdk_flutter/xsdk/framework/base/xsdk_function.dart';
import 'package:xsdk_flutter/xsdk/framework/bean/x_bean_data_table.dart';
import 'package:xsdk_flutter/xsdk/operation/x_constant_temp.dart';
import 'package:xsdk_flutter/xsdk/utils/data_table/bean/x_bean_sf_datagrid.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:syncfusion_flutter_core/theme.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_image.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_log.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_style.dart';
import 'package:xsdk_flutter/xsdk/utils/x_utils_widget.dart';

abstract class XDataTableUtils{


  /*
  SfDataGrid 这里不能上下滚动,固定高度
  https://pub-web.flutter-io.cn/packages/syncfusion_flutter_datagrid
  https://help.syncfusion.com/flutter/datagrid/load-more
  dependencies:
    syncfusion_flutter_datagrid: ^22.1.39
  import 'package:syncfusion_flutter_datagrid/datagrid.dart';

  也可嵌套在CustomScrollView中,但要使用SliverToBoxAdapter包裹;
  也可以嵌套在SingleChildScrollView中
  判断<5列时,自动占满宽度,创建GridColumn设置columnWidthMode = ColumnWidthMode.fill,

  注意:
  更新分页数据,设置:isPageLoadData=true,传入loadMoreDataFunction(内部调用分页加载api)
  由于verticalScrollController刷新界面停留当前位置ui空白的bug,不能使用setSate()更新,
  而要利用在loadMoreDataFunction中的XSfDataSource: source.updatePageData()更新替代即可,

  isPageLoadData:true,
  loadMoreDataFunction: (XSfDataSource source){
              if(widget.currentPageIndex<widget.totalPages){
                _getPageData(pageIndex:widget.currentPageIndex+1,source:source);
              }else{
                toast('已是最后一页');
                source.updateWidget();
              }
            },

  @override
  Future<void> updateData({int pageIndex = 1}) async {
    //查找数据库
    _getPageData(pageIndex:pageIndex);
  }

  //获得分页数据
  void _getPageData(
      {
        required int pageIndex,
        XSfDataSource? source,
      }
      ){

    showLoading();
    Future((){
      Map<String,dynamic> map=XObjectBoxUtils.getDBStockTempCurrentAllStockItems(pageIndex: pageIndex);
      hideLoading();

      List<dynamic> data=map['data']??[];
      widget.currentPageIndex=map['pageIndex'];
      widget.totalPages=map['pageCount'];

      //每次请求返回响应重新设置为false
      XTempData.isSfDataTableLoadingMoreRows =false;
      if(widget.currentPageIndex==1){
        //请求第1页设置为false,最后1页设置为true
        XTempData.isSfDataTableNoMoreRows=false;
        //更新(从updateData()执行更新)
        setState(() {
          widget.listData.clear();
          widget.listData.addAll(data);
        });
      }else{

        if(widget.currentPageIndex==widget.totalPages){
          //请求第1页设置为false,最后1页设置为true
          XTempData.isSfDataTableNoMoreRows=true;
        }

        //更新(从内部loadMoreDataFunction加载更多中更新)
        source?.updatePageData(false, data);
      }

    });

  }

  由于iOS的滑动到底部重复触发问题,解决要添加自定义标记拦截:
   XTempData.isSfDataTableNoMoreRows: 请求第1页设置为false,最后1页设置为true
   XTempData.isSfDataTableLoadingMoreRows 每次请求返回响应重新设置为false
   */
  static Widget getWidgetSfDataGrid(
      {
        //列标签
        required List<dynamic> columnsData,
        required XFunctionSfDataGridColumnItem columnItemBuildFunction,
        XFunctionWidgetOnClick<XSfDataGridColumn>? onColumnItemClick,
        //行数据
        required List<dynamic> listData,
        required XFunctionSfDataGridRowItem rowItemBuildFunction,
        XFunctionSfDataGridCellOnTap? onCellTap,
        XFunctionSfDataGridCellOnDoubleTap? onCellDoubleTap,
        XFunctionSfDataGridCellOnLongTap? onCellLongTap,
        //注意DataTable本身不能对数据进行排序，这些参数仅仅是外观上的控制
        int? currentSortColumnIndex,//设置显示当前排序图标的列(外部传入)
        bool currentSortAscending=false,//当前排序顺序,默认降序排列(外部传入)
        double headerRowHeight=49,//表格标题高度
        double rowHeight=49,//表格标题高度
        int frozenColumnsCount=0,//冻结多少列(从最左边第1列算起)
        int frozenRowsCount=0,//冻结多少行(从第一行算起,不包括标题)
        int footerFrozenColumnsCount=0,//冻结多少列(从最右边最后1列算起)
        int footerFrozenRowsCount=0,//冻结多少行(从最后一行算起)
        Widget? footer,
        double footerHeight = 38,
        DataGridController? controller,
        //ColumnWidthMode columnWidthMode=ColumnWidthMode.none,
        bool allowSorting=false,//为true时,列头显示排序图标,点击自动排列现有数据(如果要请求接口排序,则设置false,然后在列头添加点击事件控件GestureDetector)
        Color gridLineColor=const Color(0xFFEAEAEA), // 设置分割线颜色
        Color frozenPaneLineColor=Colors.transparent, // 设置冻结分割线颜色
        double? frozenPaneElevation=0,//冻结阴影
        double? frozenPaneLineWidth=0,
        double gridLineStrokeWidth=0.5,
        bool showHorizontalScrollbar = false,//实测iOS横向滚动条位置错误,少计算title高度
        bool showVerticalScrollbar = true,
        bool isPageLoadData=false,//是否分页加载数据
        XFunctionSfDataGridLoadMoreData? loadMoreDataFunction,//加载分页数据方法
        XFunctionSfDataGridNotifyXSfDataSource? notifyXSfDataSource, //通知获得XSfDataSource
        bool isScreenPortrait=true, //默认竖屏
        XFunctionSfDataGridNotifyColumnResize? notifyColumnResize,//通知列宽改变, 重设列宽值
      }
      ){

    //实测:使用自带的verticalScrollController刷新界面停留当前位置ui空白,bug???
    //ScrollController verticalScrollController=ScrollController(initialScrollOffset: initialScrollOffset);
    //因此加载更多刷新界面,不能使用setState(),利用在loadMoreDataFunction中的XSfDataSource, source.updatePageData()更新

    //
    ScrollPhysics verticalScrollPhysics=isPageLoadData?const AlwaysScrollableScrollPhysics():const NeverScrollableScrollPhysics();
    controller??=DataGridController();

    XSfDataSource source=XSfDataSource(
      data: listData,
      rowItemBuildFunction:rowItemBuildFunction,
      loadMoreDataFunction:loadMoreDataFunction,
    );

    if(notifyXSfDataSource!=null){
      notifyXSfDataSource(source);
    }

    //处理列表头
    List<XSfDataGridColumn> columns=columnsData.map((dynamic item) => columnItemBuildFunction(item)).toList();
    List<GridColumn> columnsLabels=columns.map(
            (XSfDataGridColumn item){

          //列表头文字
          Widget columnNameWidget=XWidgetUtils.getWidgetText(
            item.valueShow!=null?'${item.valueShow!}':'${item.columnName}',
            maxLines: item.textMaxLines,
            style: item.textStyle,
            padding: XWidgetUtils.getEdgeInsets(2, 0, 2, 0),
          );

          //
          return GridColumn(
            columnName: item.columnName,
            width: item.columnWidth??=double.nan,
            minimumWidth: item.columnMinWidth??=double.nan,
            maximumWidth: item.columnMaxWidth??=double.nan,
            columnWidthMode: columns.length>(isScreenPortrait?4:8)?ColumnWidthMode.none:ColumnWidthMode.fill,
            label: item.child!=null?item.child!:
            XWidgetUtils.getWidgetGestureDetector(
                child: XWidgetUtils.getLayoutContainer(
                  backgroundColor: item.backgroundColor,
                  alignment: item.alignment,
                  child: XWidgetUtils.getLayoutRow(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        columns.length==4?XWidgetUtils.getLayoutContainer(width: 58,child: columnNameWidget):columnNameWidget,
                        !item.isSortable?XWidgetUtils.getLayoutContainer():
                        item.currentSortImage==null?XWidgetUtils.getLayoutContainer():
                        XWidgetUtils.getLayoutContainer(
                          margin: XWidgetUtils.getEdgeInsets(5, 0, 0, 0),
                          child: XImageUtils.getImageWidgetWithAsset(
                            item.currentSortImage!,
                            width: item.currentSortImageWidth,
                            height: item.currentSortImageHeight,
                          ),
                        ),
                        XWidgetUtils.getWidgetText(' '),
                      ]
                  ),
                ),
                onTap:(){
                  if(onColumnItemClick!=null){
                    onColumnItemClick(item);
                  }
                }
            ),
          );
        }
    ).toList();

    return XWidgetUtils.getLayoutStack(
        // fit:StackFit.expand,
        children: [
          XWidgetUtils.getLayoutPositioned(
              left: -2,
              right: -2,
              top: 0,
              bottom: 0,
              child: XWidgetUtils.getLayoutContainer(
                  child: SfDataGridTheme(
                    data: SfDataGridThemeData(
                      gridLineColor: gridLineColor,
                      gridLineStrokeWidth: gridLineStrokeWidth,
                      frozenPaneLineColor: frozenPaneLineColor, //
                      frozenPaneElevation:frozenPaneElevation,
                      frozenPaneLineWidth:frozenPaneLineWidth,
                      // 添加更多的自定义样式...
                    ),
                    child: SfDataGrid(
                      key:UniqueKey(),
                      //columnWidthMode: ColumnWidthMode.auto,
                      //columnWidthCalculationRange: ColumnWidthCalculationRange.allRows,
                      columnWidthMode: columns.length>(isScreenPortrait?4:8)?ColumnWidthMode.none:ColumnWidthMode.fill,//columnWidthMode,
                      gridLinesVisibility:GridLinesVisibility.horizontal,
                      headerGridLinesVisibility: GridLinesVisibility.horizontal,
                      controller:controller,
                      allowSorting: allowSorting,
                      allowColumnsResizing: notifyColumnResize==null?false:true,//允许改变列宽
                      onColumnResizeEnd: notifyColumnResize==null?null:(ColumnResizeEndDetails details) {
                        //实测:使用onColumnResizeUpdate报错,

                        //更新列宽,通知更新ui
                        // setState(() {
                        //   columnWidths[details.column.columnName] = details.width;
                        // });
                        notifyColumnResize(details.column.columnName,details.width);
                        //return true;
                      },
                      shrinkWrapRows:isPageLoadData?false:true,
                      verticalScrollPhysics:verticalScrollPhysics,
                      //verticalScrollController:verticalScrollController,//实测:初始化偏移位置导致空白有bug
                      horizontalScrollPhysics:const AlwaysScrollableScrollPhysics(),
                      headerRowHeight: headerRowHeight*XTempData.deviceScreenScale,
                      rowHeight:rowHeight*XTempData.deviceScreenScale,
                      showHorizontalScrollbar:showHorizontalScrollbar,
                      showVerticalScrollbar:showVerticalScrollbar,
                      frozenColumnsCount: frozenColumnsCount,//冻结多少列(从最左边第1列算起)
                      footerFrozenColumnsCount:footerFrozenColumnsCount,//冻结多少列(从最右边最后1列算起)
                      frozenRowsCount:frozenRowsCount,//冻结多少行(从第一行算起,不包括标题)
                      footerFrozenRowsCount:footerFrozenRowsCount,//冻结多少行(从最后一行算起)
                      footerHeight:footerHeight*XTempData.deviceScreenScale,//底部bar高度
                      footer: footer,
                      loadMoreViewBuilder:!isPageLoadData?null:
                          (BuildContext context, LoadMoreRows loadMoreRows)
                      {

                        if(XTempData.isSfDataTableNoMoreRows){
                          //没有更多的数据
                          XLogUtils.printLog('---没有更多的数据');
                          return SizedBox.fromSize(size: Size.zero);
                        }else{
                          if(!XTempData.isSfDataTableLoadingMoreRows){
                            XTempData.isSfDataTableLoadingMoreRows=true;
                            XLogUtils.printLog('---datatable触发底部...');
                            Future<String> loadRows() async {
                              //分页触发在XSfDataSource的handleLoadMoreRows()
                              await loadMoreRows();
                              //return Future<String>.value('Completed');
                              return Future<String>.value('loading');
                            }

                            return FutureBuilder<String>(
                              initialData: 'loading',
                              future: loadRows(),
                              builder: (context, snapShot) {
                                if (snapShot.data == 'loading') {
                                  return _getBottomLoadingMoreRowsWidget();
                                } else {
                                  return SizedBox.fromSize(size: Size.zero);
                                }
                              },
                            );
                          }else{
                            return _getBottomLoadingMoreRowsWidget();
                          }
                        }

                      },
                      //行数据下标从1开始 因此实际数据要-1才是list的下标值
                      onCellTap: (DataGridCellTapDetails details){
                        if(onCellTap!=null){
                          onCellTap(details.rowColumnIndex.rowIndex-1,details.column.columnName,details.rowColumnIndex.columnIndex);
                        }
                      },
                      onCellDoubleTap: (DataGridCellDoubleTapDetails details){
                        if(onCellDoubleTap!=null){
                          onCellDoubleTap(details.rowColumnIndex.rowIndex-1,details.column.columnName,details.rowColumnIndex.columnIndex);
                        }
                      },
                      onCellLongPress: (DataGridCellLongPressDetails details){
                        if(onCellLongTap!=null){
                          onCellLongTap(details.rowColumnIndex.rowIndex-1,details.column.columnName,details.rowColumnIndex.columnIndex);
                        }
                      },
                      source: source,
                      columns: columnsLabels,
                    ),
                  )
              )

          )
        ]);
  }


  static Widget _getBottomLoadingMoreRowsWidget(){
    return XWidgetUtils.getLayoutContainer(
      backgroundColor: Colors.white70,
      alignment: Alignment.center,
      height: 30,
      child: XWidgetUtils.getLayoutRow(
          mainAxisSize:MainAxisSize.min,
          mainAxisAlignment:MainAxisAlignment.center,
          children: [
            const SizedBox(
                width: 20,height: 20,
                child:CircularProgressIndicator(
                  strokeWidth: 2.0,
                  // backgroundColor: Colors.blue,
                  // valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
                )
            ),
            XWidgetUtils.getWidgetText('加载更多',style: XStyleUtils.textStyle_666_12(),padding: XWidgetUtils.getEdgeInsets(10, 0, 0, 0))
          ]
      ),
    );
  }

  /*
  嵌套scrollview支持加载更多(不推荐,无法冻结头部标题栏)
   */
  static Widget getWidgetSfDataGridWithScroll(
      {
        //列标签
        required List<dynamic> columnsData,
        required XFunctionSfDataGridColumnItem columnItemBuildFunction,
        //行数据
        required List<dynamic> listData,
        required XFunctionSfDataGridRowItem rowItemBuildFunction,
        XFunctionSfDataGridCellOnTap? onCellTap,
        XFunctionSfDataGridCellOnDoubleTap? onCellDoubleTap,
        XFunctionSfDataGridCellOnLongTap? onCellLongTap,
        //注意DataTable本身不能对数据进行排序，这些参数仅仅是外观上的控制
        int? currentSortColumnIndex,//设置显示当前排序图标的列(外部传入)
        bool currentSortAscending=false,//当前排序顺序,默认降序排列(外部传入)
        double headerRowHeight=38,//表格标题高度
        double rowHeight=49,//表格标题高度
        int frozenColumnsCount=0,//冻结多少列(从最左边第1列算起)
        int frozenRowsCount=0,//冻结多少行(从第一行算起,不包括标题)
        int footerFrozenColumnsCount=0,//冻结多少列(从最右边最后1列算起)
        int footerFrozenRowsCount=0,//冻结多少行(从最后一行算起)
        Widget? footer,
        double footerHeight = 38,
        DataGridController? controller,
        bool allowSorting=false,//为true时,列头显示排序图标,点击自动排列现有数据(如果要请求接口排序,则设置false,然后在列头添加点击事件控件GestureDetector)
        Color gridLineColor=const Color(0xFFEAEAEA), // 设置分割线颜色
        Color frozenPaneLineColor=const Color(0xFFEAEAEA), // 设置冻结分割线颜色
        bool showHorizontalScrollbar = false,//实测iOS横向滚动条位置错误,少计算title高度
        bool showVerticalScrollbar = true,
        double initialScrollOffset=0.0,
        XFunctionEventNotify<ScrollController>? onNotifyScrollStop,//停止滚动通知,更新外界传入的scrollview的初始化位置
        XFunctionEventNotify? onNotifyScrollBottomPosition,//滚动到底部通知
        XFunctionSfDataGridNotifyColumnResize? notifyColumnResize,//通知列宽改变, 重设列宽
      }
      ){

    Widget tableDataWidget= getWidgetSfDataGrid(
      columnsData:columnsData,
      columnItemBuildFunction:columnItemBuildFunction,
      listData:listData,
      rowItemBuildFunction:rowItemBuildFunction,
      onCellTap:onCellTap,//行数据下标从1开始
      onCellDoubleTap:onCellDoubleTap,//行数据下标从1开始
      onCellLongTap:onCellLongTap,//行数据下标从1开始
      currentSortColumnIndex:currentSortColumnIndex,//设置显示当前排序图标的列(外部传入)
      currentSortAscending:currentSortAscending,//当前排序顺序,默认降序排列(外部传入)
      headerRowHeight:headerRowHeight,//表格标题高度
      rowHeight:rowHeight,//表格标题高度
      frozenColumnsCount:frozenColumnsCount,//冻结多少列(从最左边第1列算起)
      frozenRowsCount:frozenRowsCount,//冻结多少行(从第一行算起,不包括标题)
      footerFrozenColumnsCount:footerFrozenColumnsCount,//冻结多少列(从最右边最后1列算起)
      footerFrozenRowsCount:footerFrozenRowsCount,//冻结多少行(从最后一行算起)
      footer:footer,
      footerHeight:footerHeight,
      controller:controller,
      allowSorting:allowSorting,//为true时,列头显示排序图标,点击自动排列现有数据(如果要请求接口排序,则设置false,然后在列头添加点击事件控件GestureDetector)
      gridLineColor:gridLineColor, // 设置分割线颜色
      frozenPaneLineColor:frozenPaneLineColor, // 设置冻结分割线颜色
      showHorizontalScrollbar:showHorizontalScrollbar,//实测iOS横向滚动条位置错误,少计算title高度
      showVerticalScrollbar:showVerticalScrollbar,
      notifyColumnResize:notifyColumnResize,
    );

    return XWidgetUtils.getLayoutSingleChildScrollView(
        initialScrollOffset:initialScrollOffset,
        onNotifyScrollStop: onNotifyScrollStop,
        onNotifyScrollBottomPosition:onNotifyScrollBottomPosition,
        child:tableDataWidget
    );

  }


  //原生控件:DataTable/////////////////////////////////////////////////

  /*
  原生控件:DataTable控件显示表格数据,与Gridview类似,但它是用来显示行数据
  注意:
  由于DataTable本身是不具备滑动属性，所以当数据比较多的时候需要嵌套滑动组件，
  这里我们使用两个SingleChildScrollView来完成纵向横向的滑动,参照x_page_state_datatable.dart

  也可嵌套在CustomScrollView中,但要使用SliverToBoxAdapter包裹;


  第三方库:
  https://pub.flutter-io.cn/packages/syncfusion_flutter_datagrid
  https://pub-web.flutter-io.cn/packages/pluto_grid
  https://pub-web.flutter-io.cn/packages/data_table_2
  https://weblaze.dev/pluto_grid/build/web/#feature/column-freezing

   */
  static DataTable getWidgetDataTable(
      {
        //列标签
        required List<XBeanDataTableLabel> columnsLabels,
        //行数据
        required List<dynamic> listData,
        required XFunctionDataRowItem rowItemBuildFunction,
        //注意DataTable本身不能对数据进行排序，这些参数仅仅是外观上的控制
        int? currentSortColumnIndex,//设置显示当前排序图标的列(外部传入)
        bool currentSortAscending=false,//当前排序顺序,默认降序排列(外部传入)
        Color headingRowColor=Colors.white,
        double headingRowHeight=48,
        TableBorder? border,
      }
      ){
    return DataTable(
      //border:TableBorder(),//table行列和外边框,
      headingRowColor: WidgetStatePropertyAll(headingRowColor),
      headingRowHeight: headingRowHeight*XTempData.deviceScreenScale,
      columnSpacing:0,//列间隔
      horizontalMargin:0,//table左右间隔
      dividerThickness:0,
      dataRowColor: const WidgetStatePropertyAll(Colors.white),
      //decoration: XWidgetUtils.getBoxDecoration(border: const Border(),backgroundColor: Colors.white),
      showBottomBorder:true,
      showCheckboxColumn:false,
      columns: columnsLabels.map((XBeanDataTableLabel label){

        //MainAxisAlignment headingRowAlignment;
        TextAlign textAlign;
        if(label.alignment==Alignment.centerLeft || label.alignment==Alignment.topLeft || label.alignment==Alignment.bottomLeft){
          textAlign=TextAlign.start;
          //headingRowAlignment=MainAxisAlignment.start;
        }else if(label.alignment==Alignment.centerRight || label.alignment==Alignment.topRight || label.alignment==Alignment.bottomRight){
          textAlign=TextAlign.end;
          //headingRowAlignment=MainAxisAlignment.end;
        }else{
          textAlign=TextAlign.center;
          //headingRowAlignment=MainAxisAlignment.center;
        }

        return DataColumn(
          //headingRowAlignment: headingRowAlignment,  //flutter旧版不支持
          label: XWidgetUtils.getLayoutContainer(
              width: label.columnWidth,
              height: headingRowHeight*XTempData.deviceScreenScale,
              backgroundColor: label.backgroundColor,
              child: XWidgetUtils.getWidgetText(
                label.text,
                textAlign: textAlign,
                style: label.style,
              ),
              alignment:label.alignment
          ),
          //长按提示
          tooltip: label.tooltip,
          //是否靠右对齐
          //numeric: !label.isAlignLeft,
          onSort: label.onSort,
          //columnWidth:FlexColumnWidth(), //flutter旧版不支持
        );
      }).toList(),
      //行数据
      rows: listData.map((dynamic item){
        return rowItemBuildFunction(item);
      }).toList(),
      //默认降序
      sortAscending: currentSortAscending,
      //显示排序图标
      sortColumnIndex: currentSortColumnIndex,
    );
  }

}